﻿/**
 * Creation Date : December 15 2008
 * Author : Abdelkrim BOUTKHIL
 * 
 * Modification Date :
 * Modified by : 
 **/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Plugins;
using NLog;
using System.ComponentModel.Composition;
using DataAccess;
using System.Data.Linq;
using Net.Mail;
using System.Configuration;
using System.IO;

namespace Plugins
{
    /// <summary>
    /// This is a CollaMail Plugin.
    /// This plugin's role is to retrieve all mails, download them and save them to the database.
    /// </summary>
    [Export(typeof(IPlugin))]
    public class MailRetriever : IPlugin
    {
        private static Logger _logger = LogManager.GetCurrentClassLogger();
        /// <summary>
        /// Utilisation d'un DataContext tout au long des traitements du plugin.
        /// </summary>
        private CollaMailDataContext _dataContext;
        /// <summary>
        /// Le client Pop3 utilisé pour récupérer les messages depuis le serveur.
        /// </summary>
        private Pop3Client _pop3Client;

        /// <summary>
        /// Récupère les mails depuis le serveur.
        /// </summary>
        private void FetchAndProcessMails()
        {
            _pop3Client.Authenticate();

            List<Pop3ListItem> items = _pop3Client.List();
            _logger.Info("{0} new messages on server", items.Count);
            foreach (Pop3ListItem item in items)
            {
                SaveMessage(_pop3Client.RetrMailMessageEx(item));
                //_pop3Client.Dele(item);
            }
            _pop3Client.Quit();
        }

        /// <summary>
        /// Saves the message and its attachments to the DataBase
        /// </summary>
        /// <param name="message">the message to save</param>
        private void SaveMessage(MailMessageEx mail)
        {
            
            Message message = new Message()
            {
               
                Body = mail.Body,
                Object = mail.Subject
            };
            _dataContext.Messages.InsertOnSubmit(message);
            _dataContext.SubmitChanges();
            List<Attachment> attachments = new List<Attachment>();
            foreach (System.Net.Mail.Attachment pj in mail.Attachments)
            {
                Attachment attachment = new Attachment()
                {
                    Message = message,
                    Url = "attachments/" + message.Id + "/" + pj.Name
                };
                string saveDirectory = "attachments\\" + message.Id + "\\";
                if (!Directory.Exists(saveDirectory))
                    Directory.CreateDirectory(saveDirectory);
                SaveStreamToFile(pj.ContentStream, saveDirectory + pj.Name);
                attachments.Add(attachment);
            }
            _dataContext.Attachments.InsertAllOnSubmit(attachments);
            _dataContext.SubmitChanges();
        }

        /// <summary>
        /// Ecrit le contenu stream dans un nouveau fichier
        /// </summary>
        /// <param name="readStream">Le stream à écrire</param>
        /// <param name="filename">Le chemin complet du fichier</param>
        private void SaveStreamToFile(Stream readStream, string filename)
        {
            FileStream writeStream = new FileStream(filename, FileMode.Create, FileAccess.Write);
            int Length = 256;
            Byte[] buffer = new Byte[Length];
            int bytesRead = readStream.Read(buffer, 0, Length);
            while (bytesRead > 0)
            {
                writeStream.Write(buffer, 0, bytesRead);
                bytesRead = readStream.Read(buffer, 0, Length);
            }
            readStream.Close();
            writeStream.Close();
        }

        #region IPlugin Members

        void IPlugin.Start()
        {
            _dataContext = Connexion.getDataContext();
            _pop3Client = ((Pop3ClientSection)ConfigurationManager.GetSection("Pop3ClientSection")).getClient();
            FetchAndProcessMails();
            _logger.Trace("Plugin started");
        }

        void IPlugin.End()
        {
            _dataContext.Dispose();
            _pop3Client.Dispose();
            _logger.Trace("Plugin ended");
        }

        #endregion


    }
}
